﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Xml;
using System.Windows.Forms;
using System.Collections;

using EBFHelper.Nodes;
using EBFHelper.forms;

namespace EBFHelper.EBFHelperUtil
{
    public static class HelperUtil
    {
        public static void checkProjectItemNode(EnvDTE.ProjectItems projectItems, List<EnvDTE.ProjectItem> pItems)
        {
            foreach (EnvDTE.ProjectItem pi in projectItems)
            {
                //判断是否为三个重要节点
                if (pi.Name.Equals("Actions") || pi.Name.Equals("Operations") || pi.Name.Equals("OpSteps"))
                {
                    pItems.Add(pi);
                }
                if (pItems.Count >= 2)
                {
                    break;//起码找到了ACTIONS 以及Operations节点
                }
                //没有子节点
                if (pi.ProjectItems != null)
                {
                    checkProjectItemNode(pi.ProjectItems, pItems);
                }
            }
        }

        public static void findNodeList(EnvDTE.ProjectItem parentItem, List<iNode> iNodes, int style)
        {
            foreach (EnvDTE.ProjectItem pi in parentItem.ProjectItems)
            {
                if (0 == style)
                {
                    ActionXmlNode actionXmlNode = new ActionXmlNode();
                    actionXmlNode.projectItem = pi;
                    actionXmlNode.parentItem = parentItem;
                    actionXmlNode.name = pi.Name;
                    iNodes.Add(actionXmlNode);
                }
                else if (1 == style)
                {
                    OperationXmlNode operationXmlNode = new OperationXmlNode();
                    operationXmlNode.projectItem = pi;
                    operationXmlNode.parentItem = parentItem;
                    operationXmlNode.name = pi.Name;
                    iNodes.Add(operationXmlNode);
                }
                if (pi.ProjectItems != null)
                {
                    findNodeList(pi, iNodes, style);
                }
            }

        }

        public static void findActionsAndOperationsAndOpstepsList(List<EnvDTE.ProjectItem> pItems, List<iNode> actionNodes, List<iNode> operationNodes)
        {
            foreach (EnvDTE.ProjectItem pi in pItems)
            {
                //遍历ACTIONS文件夹中的每一个元素
                if (pi.Name.Equals("Actions"))
                {
                    HelperUtil.findNodeList(pi, actionNodes, 0);
                }
                //遍历operations文件夹中的每一个元素
                else if (pi.Name.Equals("Operations"))
                {
                    HelperUtil.findNodeList(pi, operationNodes, 1);
                }
            }
        }

        public static List<iNode> findXmlNodeList(List<iNode> iNodes)
        {
            List<iNode> xmlNodeList = new List<iNode>();
            foreach (iNode inode in iNodes)
            {
                if (!inode.projectItem.Name.EndsWith(".xml"))
                {
                    continue;
                }
                xmlNodeList.Add(inode);
            }
            return xmlNodeList;
        }

        public static void buildOperationTree(XmlNodeList xmlNodeList,TreeNodeCollection treeNodes)
        {
            string sValue;
            foreach (XmlNode xmlNode in xmlNodeList)
            {
                if (xmlNode.NodeType == XmlNodeType.Element)  //只对element类型的节点进行处理
                {
                    MyTreeNode tNode = new MyTreeNode();
                    sValue = "";

                    if (xmlNode.HasChildNodes 
                        && xmlNode.ChildNodes.Count ==1 
                        && xmlNode.ChildNodes[0].NodeType == XmlNodeType.Text)//具备text类型的子节点
                    {
                        tNode.name = xmlNode.Name;
                        sValue = xmlNode.ChildNodes[0].Value;
                    }
                    else
                    {
                        for(int j=0;j<xmlNode.Attributes.Count;j++)
                        {
                            sValue += xmlNode.Attributes[j].Name + "=" + xmlNode.Attributes[j].Value + ";";
                            
                            tNode.attributes[xmlNode.Attributes[j].Name] = xmlNode.Attributes[j].Value;
                        }
                        tNode.name = xmlNode.Name;
                        tNode.Text = xmlNode.Name + ":" + sValue;
                        if (xmlNode.Name.Equals("EBOperation")
                            || xmlNode.Name.Equals("opStepGroup")
                            || xmlNode.Name.Equals("opStep"))
                        {
                            tNode.ForeColor = Color.FromName("SlateBlue");
                        }
                        else if (xmlNode.Name.Equals("refFormat")
                            || xmlNode.Name.Equals("fmtDef"))
                        {
                            tNode.ForeColor = Color.FromName("Red");
                         } 
                    }

                    treeNodes.Add(tNode);

                    if (xmlNode.HasChildNodes)
                    {
                        buildOperationTree(xmlNode.ChildNodes, tNode.Nodes);
                    }
                }
                
            }
        }

        public static void addOperationXmlNodeToActionXmlNode(List<iNode> actionXmlList, List<iNode> operationXmlList, List<iNode> activeActionXmlList, AutoCompleteStringCollection ACSC)
        { 
            foreach (iNode inode in actionXmlList)
            {
                //ActionXmlNode actionXmlNode =(ActionXmlNode) inode;
                ActionXmlNode actionXmlNode;
                if (null == (actionXmlNode = inode as ActionXmlNode))
                {
                    continue;
                }
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.Load(actionXmlNode.projectItem.FileNames[1]);
                XmlNode ebOperation = xmlDoc.SelectSingleNode("//Action_Config//OperationAction");
                if (null == ebOperation)
                {
                    continue;
                }
                XmlElement xn = (XmlElement)ebOperation;
                string eo = xn.GetAttribute("operationName");
                if (string.IsNullOrEmpty(eo))
                {
                    continue;
                }
                foreach (iNode operationNode in operationXmlList)
                {
                    if (operationNode.projectItem.Name.Contains(eo))
                    {
                        actionXmlNode.operationNode = operationNode;
                        activeActionXmlList.Add(actionXmlNode);
                        ACSC.Add(actionXmlNode.name);
                        break;//防止重复
                    }
                }


            }
        }

        public static void addOperationNodeAtrributeToAtrributeBox(MyTreeNode tNode,GroupBox AttributeBox) 
        {
             int i = 0;                      //放在循环之外定义减少CPU负担
             double scaleKey = 0.15;
             double scaleValue = 0.60;
             int rangeKey = (int)(scaleKey * AttributeBox.Width);
             int rangeValue = (int)(scaleValue * AttributeBox.Width);
             int height = 24;
             int left = 0;
             int cross = rangeKey;

             foreach (DictionaryEntry de in tNode.attributes)
             {     
                 AttributeBox.Text = tNode.name;
                 TextBox tbAN = new TextBox();
                 tbAN.Text = de.Key.ToString();
                 tbAN.Width = rangeKey;
                 tbAN.Left = left;
                 tbAN.Top = height + height * i;
                 TextBox tbAV = new TextBox();
                 tbAV.Text = de.Value.ToString();
                 tbAV.Left = tbAN.Right + cross;
                 tbAV.Width = rangeValue;
                 tbAV.Top = tbAN.Top;
                 AttributeBox.Controls.Add(tbAN);
                 AttributeBox.Controls.Add(tbAV);
                 i++;
             }
        }

        public static void addActionNodeAttributeToAttributeWindow(XmlNodeList childNodes,ActionXmlNodeDetailInfo aXNDI) 
        {
            int i = 0;
            double scaleId = 0.05;
            double sacleSite = 0.70;
            int rangeId = (int)(scaleId * aXNDI.ForwardSiteBox.Width);
            int rangeSite = (int)(sacleSite * aXNDI.ForwardSiteBox.Width);
            int height = 24;
            int left = 0;
            int cross = rangeId;
            foreach (XmlNode xmlNode in childNodes)
            {
                if (xmlNode.NodeType == XmlNodeType.Element)//只对Element类型的的节点进行处理 
                {
                    switch (xmlNode.Name)
                    {
                        case "field" :
                            aXNDI.RegistryIdText.Text = xmlNode.Attributes[0].Value;
                            aXNDI.RegistryTypeText.Text = xmlNode.Attributes[1].Value;
                            break;
                        case "OperationAction":
                            aXNDI.ActionNameText.Text = xmlNode.Attributes[0].Value;
                            aXNDI.OperationNameText.Text = xmlNode.Attributes[1].Value;
                            aXNDI.BusinessCodeText.Text = xmlNode.Attributes[2].Value;
                            aXNDI.LocationText.Text = xmlNode.Attributes[3].Value;
                            break;
                        case "channelName":
                            aXNDI.ChannelText.Text = xmlNode.Attributes[0].Value;
                            break;
                        case "localeCode":
                            aXNDI.LanguageText.Text = xmlNode.Attributes[0].Value;
                            break;
                        case "forward":
                            TextBox tbID = new TextBox();
                            tbID.Text = xmlNode.Attributes[0].Value;
                            tbID.Width = rangeId;
                            tbID.Height = height;
                            tbID.Left = left;
                            tbID.Top =height+height * i;
                            TextBox tbFS = new TextBox();
                            tbFS.Text = xmlNode.Attributes[1].Value;
                            tbFS.Left = tbID.Right + cross;
                            tbFS.Width = rangeSite;
                            tbFS.Height = height;
                            tbFS.Top = tbID.Top;
                            aXNDI.ForwardSiteBox.Controls.Add(tbID);
                            aXNDI.ForwardSiteBox.Controls.Add(tbFS);
                            i++;
                            break;
                        default:
                            break;
                    }
                    if (xmlNode.HasChildNodes)
                    {
                        addActionNodeAttributeToAttributeWindow(xmlNode.ChildNodes,aXNDI);
                    }
                }
            }
        }

        public static void bindSourceToTextBox(ListBox listBox,object obj) 
        {
            BindingSource bs = new BindingSource();
            bs.DataSource = obj;
            listBox.DataSource = bs;
            listBox.DisplayMember = "name";
        }
    }
}
